package com.coincalf.web;

import com.coincalf.entity.Coin;
import com.coincalf.framework.dto.CoinRechargeDTO;
import com.coincalf.framework.enums.BusinessType;
import com.coincalf.framework.enums.RechargeStatus;
import com.coincalf.framework.exception.BlockException;
import com.coincalf.framework.exception.GlobalDefaultException;
import com.coincalf.framework.http.Response;
import com.coincalf.framework.utils.SignUtil;
import com.coincalf.service.AccountService;
import com.coincalf.service.CoinService;
import com.coincalf.service.impl.SmsServiceImpl;
import com.coincalf.user.dto.UserDTO;
import com.coincalf.user.feign.UserServiceClient;
import com.coincalf.wallet.feign.CoinRechargeServiceClient;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
import java.util.concurrent.ExecutionException;

/**
 * 资产管理控制类
 * by crow
 * 2018年5月14日18:31:05
 */
@Slf4j
@RestController
@RequestMapping("/account")
@Api(value = "数字货币-资产管理", description = "数字货币-资产管理")
public class AccountController {

    @Autowired
    private AccountService accountService;
    @Autowired
    private UserServiceClient userServiceClient;
    @Autowired
    private CoinRechargeServiceClient coinRechargeServiceClient;
    @Autowired
    private CommonController commonController;
    @Autowired
    private CoinService coinService;

    /**
     * 资金账户列表
     *
     * @return
     */
    @GetMapping(value = "/accounts")
    @ApiOperation(value = "资金账户列表", notes = "资金账户", httpMethod = "GET")
    //@PreAuthorize("isAuthenticated()")
    //@ApiOperation(value = "资金账户列表", notes = "资金账户", httpMethod = "GET", authorizations = {@Authorization(value = "Authorization")})
    public Response accounts(HttpServletRequest request) {
        Long userId = commonController.getUserId(request);
        try {
            return Response.ok(accountService.countAssets(userId));
        } catch (ExecutionException e) {
            e.printStackTrace();
            throw new GlobalDefaultException(-1);
        }
    }

    /**
     * 创新交易账户资产
     *
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "coinId", value = "币种ID", dataType = "long", paramType = "path")
    })
    @ApiOperation(value = "创新交易账户资产", httpMethod = "GET")
    @GetMapping("/funds/{coinId}")
    //@PreAuthorize("isAuthenticated()")
    //@ApiOperation(value = "创新交易账户资产", httpMethod = "GET", authorizations = {@Authorization(value = "Authorization")})
    public Object forexAsset(HttpServletRequest request, @PathVariable Long coinId) {
        Long userId = commonController.getUserId(request);
        return Response.ok(accountService.forexAsset(userId, coinId));
    }

    /**
     * 充值入账
     *
     * @return
     */
    @PostMapping("/recharge")
    @Transactional(rollbackFor = Exception.class)
    public void recharge() {
        coinRechargeServiceClient.queryPendingRecord().forEach(coinRecharge -> {
            Coin coin = coinService.queryById(coinRecharge.getCoinId());
            if (coin == null) {
                log.warn("没有该币种信息，暂不支持该币种 coinName={}", coinRecharge.getCoinName());
                return;
            }
            //是否支持充币校验
            if (coin.getRechargeFlag() != 1) {
                log.warn("该币种充币功能已关闭 coinName={}", coinRecharge.getCoinName());
                return;
            }
            //最小充币数量校验
            if (coinRecharge.getMum().compareTo(coin.getMinRecharge()) < 0) {
                log.warn("未达到最小充币数量 coinName={} address={} amount={} minAmount={}", coinRecharge.getCoinName(),
                        coinRecharge.getAddress(), coinRecharge.getMum(), coin.getMinRecharge());
                coinRecharge.setCollected(2);
                coinRecharge.setStatus(RechargeStatus.FEE.getCode());

                String currentTime = String.valueOf(System.currentTimeMillis());
                String randomNum = UUID.randomUUID().toString();
                String signStr = SignUtil.createSign(currentTime, randomNum);
                CoinRechargeDTO.Sign sign = new CoinRechargeDTO.Sign(currentTime, randomNum, signStr);
                coinRecharge.setSign(sign);
                coinRechargeServiceClient.modifyRechargeStatus(coinRecharge);
                return;
            }

            //USDT_ERC20 USDT_TRC20充币全部增加余额到USDT_OMNI 合并为USDT
            if (coinRecharge.getCoinName().equalsIgnoreCase("USDT_ERC20") || coinRecharge.getCoinName().equalsIgnoreCase("USDT_TRC20")) {
                coinRecharge.setCoinId(2L);
            }

            boolean result = accountService.addAmount(
                    coinRecharge.getUserId(),
                    coinRecharge.getCoinId(),
                    coinRecharge.getMum(),
                    BusinessType.RECHARGE,
                    BusinessType.RECHARGE.getDesc(),
                    coinRecharge.getId()
            );
            if (result) {
                coinRecharge.setStatus(RechargeStatus.SUCCESS.getCode());
                //短信通知用户
                UserDTO user = userServiceClient.selectById(coinRecharge.getUserId());
                try {
                    SmsServiceImpl.sendSms(user.getMobile(), "尊敬的用户，您的账号成功充值" + coinRecharge.getMum().stripTrailingZeros() + coinRecharge.getCoinName());
                } catch (Exception e) {
                    log.warn("充币到账短信提醒发送失败 e={}", e.getMessage());
                }
            } else {
                coinRecharge.setStatus(RechargeStatus.FAILED.getCode());
            }

            String currentTime = String.valueOf(System.currentTimeMillis());
            String randomNum = UUID.randomUUID().toString();
            String signStr = SignUtil.createSign(currentTime, randomNum);
            CoinRechargeDTO.Sign sign = new CoinRechargeDTO.Sign(currentTime, randomNum, signStr);
            coinRecharge.setSign(sign);
            boolean b = coinRechargeServiceClient.modifyRechargeStatus(coinRecharge);
            if (!b) {
                log.warn("修改充币交易状态失败 id={} txId={}", coinRecharge.getId(), coinRecharge.getTxid());
                throw new BlockException("修改充币交易状态失败");
            }
        });
    }

    /**
     * 同步币种账户和外汇账户
     */
    @PostMapping("/syncAccount")
    public boolean syncAccount(@RequestParam("userId") long userId) {
        return accountService.syncAccount(userId);
    }

}
